package com.sc.service.Vast_service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sc.Vast_pojo.domain.DeviceFix;
import com.sc.Vast_pojo.domain.PublicDevice;
import com.sc.Vast_pojo.dto.DeviceFixDTO;
import com.sc.Vast_pojo.dto.DeviceFixPageQueryDTO;
import com.sc.exception.AddNotAllowedException;
import com.sc.mapper.Vast_Mapper.DeviceFixMapper;
import com.sc.mapper.Vast_Mapper.DeviceMapper;
import com.sc.result.PageResult;
import com.sc.service.Vast_service.DeviceFixService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;

/**
 * @author Vast
 * @version 1.0
 * @function:设备维修记录服务层实现类
 */
@Service
@Slf4j
public class DeviceFixServiceImpl extends ServiceImpl<DeviceFixMapper, DeviceFix> implements DeviceFixService {
    @Autowired
    private DeviceFixMapper deviceFixMapper;
    @Autowired
    private DeviceMapper deviceMapper;
    @Autowired
    private RedisTemplate<String, List<DeviceFix>> redisTemplate;


    public static final String redisKey = "deviceFixPage : query";

    /**
     * 根据id查看工单详细
     *
     * @param id
     * @return
     */
    @Override
    public DeviceFix getById(Integer id) {
        return deviceFixMapper.selectById(id);
    }

    /**
     * 新建维修工单
     *
     * @param deviceFix 业务逻辑：在创建维修工单时，必须先更新设备的状态，也就是说设备的实际状态与创建维修工单设置
     *                  的状态不一致时抛出不允许异常
     */
    @Override
    @Transactional
    public void save(DeviceFixDTO deviceFixDTO) {
        if (deviceFixDTO == null) {
            throw new AddNotAllowedException("工单不能为空");
        }
        DeviceFix deviceFix = new DeviceFix();
        BeanUtils.copyProperties(deviceFixDTO, deviceFix);
        deviceFix.setFixTime(LocalDateTime.now());
        //根据关联的设备编号看当前新增的维修设备是否可以增加
        HashMap<String, Object> map = new HashMap<>();
        String fixNum = deviceFixDTO.getFixNum();
        if (fixNum == null) {
            throw new AddNotAllowedException("工单设置的编号不能为空");
        }
        map.put("device_num", fixNum);//工单设置的编号
        List<PublicDevice> publicDevices = deviceMapper.selectByMap(map);
        if (publicDevices.isEmpty() || publicDevices.get(0).getStatus() != deviceFixDTO.getResult()) {
            throw new AddNotAllowedException("当前设备设置的状态与实际不符，不允许添加");
        }
        deviceFixMapper.insert(deviceFix);
        redisTemplate.delete(redisKey);
    }

    /**
     * 根据主键更新维修工单
     *
     * @param deviceFixDTO
     * @param id
     */
    @Override
    @Transactional
    public void update(DeviceFixDTO deviceFixDTO, Integer id) {
        if (deviceFixDTO == null) {
            throw new AddNotAllowedException("工单不能为空");
        }
        DeviceFix deviceFix = new DeviceFix();
        BeanUtils.copyProperties(deviceFixDTO, deviceFix);
        deviceFix.setFixTime(LocalDateTime.now());
        //根据关联的设备编号看当前新增的维修设备是否可以增加
        HashMap<String, Object> map = new HashMap<>();
        String fixNum = deviceFixDTO.getFixNum();
        if (fixNum == null) {
            throw new AddNotAllowedException("工单设置的编号不能为空");
        }
        map.put("device_num", fixNum);//工单设置的编号
        List<PublicDevice> publicDevices = deviceMapper.selectByMap(map);
        if (publicDevices.isEmpty() || publicDevices.get(0).getStatus() != deviceFixDTO.getResult()) {
            throw new AddNotAllowedException("当前设备设置的状态与实际不符，不允许更新");
        }
        QueryWrapper<DeviceFix> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", id);
        deviceFixMapper.update(deviceFix, queryWrapper);
        redisTemplate.delete(redisKey);
    }

    /**
     * 设备维修记录删除
     *
     * @param ids
     */
    @Override
    public void delete(Integer id) {
        deviceFixMapper.deleteById(id);
        redisTemplate.delete(redisKey);
    }

    /**
     * 设备维修记录分页查询
     *
     * @param deviceFixDTO
     * @return
     */
    @Override
    public PageResult pageQuery(DeviceFixPageQueryDTO deviceFixPageQueryDTO) {

        log.info("the key is: {}", redisKey);
        List<DeviceFix> cachedRecords = redisTemplate.opsForValue().get(redisKey);

        if (cachedRecords != null && !cachedRecords.isEmpty()) {
            int total = cachedRecords.size();
            return new PageResult(total, cachedRecords);
        }

        Page<DeviceFix> page = new Page<>(deviceFixPageQueryDTO.getPage(), deviceFixPageQueryDTO.getPageSize());
        QueryWrapper<DeviceFix> queryWrapper = new QueryWrapper<>();
        String group = deviceFixPageQueryDTO.getGroup();
        String fixNum = deviceFixPageQueryDTO.getFixNum();
        String name = deviceFixPageQueryDTO.getName();
        if (group != null && !group.trim().isEmpty()) {
            queryWrapper.eq("`group`", group);
        }
        //任选其一
        if (fixNum != null && !fixNum.trim().isEmpty()) {
            queryWrapper.eq("fix_num", fixNum);
        } else if (name != null && !name.trim().isEmpty()) {
            queryWrapper.eq("`name`", name);
        }
        Page<DeviceFix> res = page(page, queryWrapper);

        long total = res.getTotal();
        List<DeviceFix> records = res.getRecords();

        if (records != null && !records.isEmpty()) {
            redisTemplate.opsForValue().set(redisKey, records);
        }
        return new PageResult(total, records);
    }
}